package service

import (
	"duoke/internal/dao"
	"duoke/internal/model/entity"
	"duoke/tables"
	"duoke/utils/gconv"
	"duoke/utils/orm"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/util/grand"
	"github.com/pkg/errors"
)

var Coupon = new(couponService)

type couponService struct{}

// 赠送用户
func (s *couponService) Give(c *gin.Context, couponId int, uid int, name string, phone string, fid int) error {
	coupon, err := dao.Coupon.Ctx(c).Where("id =? AND stock > 0 AND status = 1", couponId).One()
	if err != nil {
		return err
	}
	if coupon.IsEmpty() {
		return errors.New("赠送的卡券不存在")
	}
	insertRes, err := dao.CouponOrder.Ctx(c).Data(g.Map{
		"user_id":              uid,
		"mer_user_id":          coupon["user_id"],
		"coupon_id":            couponId,
		"order_no":             gtime.Now().Format("YmdHis") + "cogive" + gconv.String(grand.N(0, 99)),
		"coupon":               coupon.Json(),
		"coupon_type":          coupon["type"],
		"coupon_name":          coupon["name"],
		"coupon_condition":     coupon["condition"],
		"coupon_valid_num":     coupon["valid_num"],
		"coupon_valid_day":     coupon["valid_day"],
		"coupon_expire_time":   gtime.Now().Timestamp() + (gconv.Int64(coupon["valid_day"]) * 86400),
		"coupon_merchant_name": coupon["merchant_name"],
		"coupon_merchant_info": coupon["merchant_info"],
		"coupon_is_give":       coupon["is_give"],
		"coupon_max_give_num":  coupon["max_give_num"],
		"coupon_man":           coupon["man"],
		"coupon_jian":          coupon["jian"],
		"coupon_zhe":           coupon["zhe"],
		"coupon_is_one_card":   coupon["is_one_card"],
		"name":                 name,
		"phone":                phone,
		"pay_amount":           0,
		"fid":                  fid,
		"pay_status":           1,
		"pay_time":             gtime.Now().Timestamp(),
		"remark":               "拼团赠送",
	}).Insert()
	if err != nil {
		return err
	}
	if rows, _ := insertRes.RowsAffected(); rows == 0 {
		return errors.New("创建赠送卡券失败")
	}
	decRes, err := dao.Coupon.Ctx(c).Where("id", couponId).Decrement("stock", 1)
	if err != nil {
		return err
	}
	if rows, _ := decRes.RowsAffected(); rows == 0 {
		return errors.New("卡券库存扣除失败")
	}
	return nil
}
func (s *couponService) List(c *gin.Context, price float64) ([]map[string]interface{}, error) {
	user, err := Request.User(c)
	if err != nil && user.Id == 0 {
		return nil, errors.New("用户信息错误")
	}
	where := fmt.Sprintf("user_id=%d and pay_status=%d and coupon_valid_num > 0 and coupon_expire_time > %d",
		user.Id, 1, gtime.Now().Timestamp())
	if price > 0 {
		where += fmt.Sprintf(" and coupon_man <= %.2f", price)
	}
	var coupon []entity.CouponOrder
	err = dao.CouponOrder.Ctx(c).Where(where).Order("id desc").Scan(&coupon)
	if err != nil {
		return nil, errors.New("优惠券信息错误")
	}
	var list []map[string]interface{}
	for _, item := range coupon {
		g2 := gjson.New(item.Coupon).Map()
		if gconv.Int(g2["coupon_valid_num"]) > 1 && gconv.Int(g2["coupon_is_one_card"]) == 0 {
			for i := 0; i < item.CouponValidNum; i++ {
				list = append(list, map[string]interface{}{
					"id":                 item.Id,
					"man":                gconv.Float64(g2["man"]),
					"jian":               gconv.Float64(g2["jian"]),
					"zhe":                gconv.Int(g2["zhe"]),
					"name":               gconv.String(g2["name"]),
					"coupon_condition":   item.CouponCondition,
					"coupon_expire_time": item.CouponExpireTime,
					"type":               gconv.Int(g2["type"]),
				})
			}
		} else {
			list = append(list, map[string]interface{}{
				"id":                 item.Id,
				"man":                gconv.Float64(g2["man"]),
				"jian":               gconv.Float64(g2["jian"]),
				"zhe":                gconv.Int(g2["zhe"]),
				"name":               gconv.String(g2["name"]),
				"coupon_condition":   item.CouponCondition,
				"coupon_expire_time": item.CouponExpireTime,
				"type":               gconv.Int(g2["type"]),
			})
		}
	}
	return list, err
}
func (s *couponService) Infos(c *gin.Context, id int) ([]map[string]interface{}, error) {
	user, err := Request.User(c)
	if err != nil && user.Id == 0 {
		return nil, errors.New("用户信息错误")
	}
	where := fmt.Sprintf("user_id=%d and pay_status=%d and coupon_valid_num > 0 and coupon_expire_time > %d",
		user.Id, 1, gtime.Now().Timestamp())
	if id > 0 {
		where += fmt.Sprintf(" and id=%d", id)
	}
	var coupon []entity.CouponOrder
	err = dao.CouponOrder.Ctx(c).Where(where).Order("id desc").Scan(&coupon)
	if err != nil {
		return nil, errors.New("优惠券信息错误")
	}
	var list []map[string]interface{}
	for _, item := range coupon {
		g2 := gjson.New(item.Coupon).Map()
		if gconv.Int(g2["coupon_valid_num"]) > 1 && gconv.Int(g2["coupon_is_one_card"]) == 0 {
			for i := 0; i < item.CouponValidNum; i++ {
				list = append(list, map[string]interface{}{
					"id":                 item.Id,
					"man":                gconv.Float64(g2["man"]),
					"jian":               gconv.Float64(g2["jian"]),
					"zhe":                gconv.Int(g2["zhe"]),
					"name":               gconv.String(g2["name"]),
					"coupon_condition":   item.CouponCondition,
					"coupon_expire_time": item.CouponExpireTime,
					"type":               gconv.Int(g2["type"]),
				})
			}
		} else {
			list = append(list, map[string]interface{}{
				"id":                 item.Id,
				"man":                gconv.Float64(g2["man"]),
				"jian":               gconv.Float64(g2["jian"]),
				"zhe":                gconv.Int(g2["zhe"]),
				"name":               gconv.String(g2["name"]),
				"coupon_condition":   item.CouponCondition,
				"coupon_expire_time": item.CouponExpireTime,
				"type":               gconv.Int(g2["type"]),
			})
		}
	}
	return list, err
}

func (s *couponService) Use(c *gin.Context, id int) error {
	var coupon tables.CouponOrder
	// 如果存在 判断优惠券是否已经使用
	where := fmt.Sprintf("id=%d and pay_status=%d and coupon_valid_num > 0 and coupon_expire_time > %d",
		id, 1, gtime.Now().Timestamp())
	get, err := orm.Db.Where(where).Get(&coupon)
	if err != nil && !get {
		return errors.New("该优惠券不存在")
	}
	update, err := orm.Db.Where(where).Decr("coupon_valid_num", 1).Update(coupon)
	if err != nil && update != 1 {
		return errors.New("修改失败")
	}
	return err
}
